package com.wcgksoft.source.DataCi;

import com.wcgksoft.common.util.Datacollection.UtilTemperature;
import com.wcgksoft.common.util.SpringUtil;
import com.wcgksoft.common.util.getdata.AnalysisCallBack;
import com.wcgksoft.common.util.getdata.AnalysisHelper;
import com.wcgksoft.common.util.getdata.JXCTPacket;
import com.wcgksoft.common.util.getdata.Log;
import com.wcgksoft.entity.ZData.BasicData;
import com.wcgksoft.service.BasicDataService;
import com.wcgksoft.source.TcpServer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 阿良
 * @version 1.0.0
 * @ClassName ServerHandler.java
 * @Description 处理器1 阿良
 * @createTime 2020年05月02日 15:41:00
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {
  private static final BasicDataService basicDataService;
  static {
    basicDataService = SpringUtil.getBean(BasicDataService.class);
  }
  public static Map<String, ChannelHandlerContext> map = new HashMap<String, ChannelHandlerContext>();

  /*
   * ChannelInboundHandlerAdapter：ChannelInboundHandlerAdapter是ChannelInboundHandler的一个简单实现，默认情况下不会做任何处理，
   *   只是简单的将操作通过fire*方法传递到ChannelPipeline中的下一个ChannelHandler中让链中的下一个ChannelHandler去处理。
   *
   * SimpleChannelInboundHandler：SimpleChannelInboundHandler支持泛型的消息处理，默认情况下消息处理完将会被自动释放，无法提供
   *   fire*方法传递给ChannelPipeline中的下一个ChannelHandler,如果想要传递给下一个ChannelHandler需要调用ReferenceCountUtil#retain方法。
   * */
/*

  @Override
  public void channelActive(ChannelHandlerContext ctx) throws Exception {
    while (true) {
      byte[] b1 = {0x01, 0x03, 0x00, 0x0d,0x00,0x01,(byte) 0x15, (byte) 0xc9};
      ByteBuf buf = Unpooled.buffer();
      buf.writeBytes(b1);
      //ctx.write(b1);
      //写消息：先得到channel，在写如通道然后flush刷新通道把消息发出去。
      ctx.channel().writeAndFlush(buf);
      Thread.sleep(2000);
    }
  }
*/
  /**
   * @param name  名称
   * @param datas 数据
   */
  protected void analysis(final String name, byte[] datas) {
    AnalysisHelper.solution(datas, new AnalysisCallBack() {
      public void onSuccess(JXCTPacket packet) {
        Log.print(name + " -> " + packet);
        List<String> body = packet.getBody();
        for (int i = 0; i < body.size() / 4; i++) {
          BasicData data1 = new BasicData();
          data1.setAcquisitiontime(new Date());
          data1.setNo(packet.getDeviceNumber());
          String hex = AnalysisHelper.getParseVal(body, i * 4, 4);
          double val = AnalysisHelper.getAnalysisVal(hex);
          java.text.DecimalFormat df =new java.text.DecimalFormat("#.0");

          switch (i){
            case 0:
              System.out.println("温度");
              data1.setCom("通道"+i);
              data1.setData(String.valueOf(df.format(val*0.1)));
              data1.setHmdata(String.valueOf(df.format(val*0.1)));
              data1.setDatatype("wd");
              if((val*0.1)>100||(val*0.1)<0){
                System.out.println("出现异常数据！待捕捉！");
              }else{
                basicDataService.save(data1);
              }

              break;
            case 1:
              System.out.println("湿度");
              data1.setCom("通道"+i);
              data1.setData(String.valueOf(df.format(val*0.1)));
              data1.setHmdata(String.valueOf(df.format(val*0.1)));
              data1.setDatatype("sd");
              if((val*0.1)>100||(val*0.1)<0){
                System.out.println("出现异常数据！待捕捉！");
              }else{
                basicDataService.save(data1);
              }
              break;
            case 2:
              System.out.println("光照");
              data1.setCom("通道"+i);
              data1.setData(String.valueOf(val));
              data1.setHmdata(String.valueOf(val));
              data1.setDatatype("gzqd");
              if(val>2000||val<0){
                System.out.println("出现异常数据！待捕捉！");
              }else{
                basicDataService.save(data1);
              }
              break;
            case 3:
              System.out.println("二氧化碳");
              data1.setCom("通道"+i);
              data1.setData(String.valueOf(val));
              data1.setHmdata(String.valueOf(val));
              data1.setDatatype("co2");
              if(val>5000||val<0){
                System.out.println("出现异常数据！待捕捉！");
              }else{
                basicDataService.save(data1);
              }
              break;
            case 4:
              System.out.println("氨气");
              data1.setCom("通道"+i);
              data1.setData(String.valueOf(val*0.01));
              data1.setHmdata(String.valueOf(val*0.01));
              data1.setDatatype("aq");
              if((val*0.1)>1000||(val*0.1)<0){
                System.out.println("出现异常数据！待捕捉！");
              }else{
                basicDataService.save(data1);
              }
              break;
            case 5:
              System.out.println("信号强度");
              data1.setCom("通道"+i);
              data1.setData(String.valueOf(val));
              data1.setHmdata(String.valueOf(val));
              data1.setDatatype("signal");
              if(val>100||val<0){
                System.out.println("出现异常数据！待捕捉！");
              }else{
                basicDataService.save(data1);
              }
              break;
            case 6:
              System.out.println("错误码"+val);
              break;
            case 7:
              System.out.println("版本号"+val*0.1);
              break;
            default:
              System.out.println("数据解析出现问题");
          }
          //Log.print((i + 1) + " : " + hex + "  -> " + val);
        }
      }

      public void onFailure(String msg) {
        Log.print(name + " -> " + msg);
      }
    });
  }
  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    System.out.println("ServerHandler receive msg:" + msg.toString());

    try {
      ByteBuf buf = (ByteBuf) msg;
      //创建目标大小的数组
      byte[] barray = new byte[buf.readableBytes()];
      //把数据从bytebuf转移到byte[]
      buf.getBytes(0, barray);
      //将byte[]转成字符串用于打印
      String line = bytesToHexString(barray);
      String url = ctx.channel().remoteAddress().toString();//设备请求地址（个人将设备的请求地址当作 map 的key）
      String ip = url.substring(1, url.length() - 6);
      analysis(ip, barray);//解析数据
      ctx.fireChannelRead(msg);
      buf.release();
    } catch (Exception e) {
      System.out.println(e.getMessage());
      e.printStackTrace();
    } finally {
      //buf.release();
    }
    ctx.fireChannelRead(msg);

  }

  /**
   * 字节数组转16进制
   *
   * @param bytes 需要转换的byte数组
   * @return 转换后的Hex字符串
   */
  public static String bytesToHex(byte[] bytes) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < bytes.length; i++) {
      String hex = Integer.toHexString(bytes[i] & 0xFF);
      if (hex.length() < 2) {
        sb.append(0);
      }
      sb.append(hex);
    }
    return sb.toString();
  }


  /**
   * byte[]数组转换为16进制的字符串
   *
   * @param bytes 要转换的字节数组
   * @return 转换后的结果
   */
  public static String bytesToHexString(byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < bytes.length; i++) {
      String hex = Integer.toHexString(0xFF & bytes[i]);
      if (hex.length() == 1) {
        sb.append('0');
      }
      sb.append(hex + " ");
    }
    return sb.toString();
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    cause.printStackTrace();
    ctx.close();
  }

}

